﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;

using MT.eVotePRS.Device;
using MT.eVotePRS.Model;
// using MT.eVotePRS.Service;

using MT.eVotePRS.Presentation;
using MT.eVotePRS.Presentation.Logic;

namespace MT.eVotePRS.Presentation.Presenter
{
    public class CheckOutPresenter
    {
        private ArsProcessSchedule schedule;

        private IDeviceAPIHelper arsHelper;

        private IViewCheckOut view;

        private StudentActions studentAction;
        private HandsetActions handsetAction;
        private InventoryTxnActions txnAction;

        public StudentActions StudentAction
        {
            get { return studentAction; }
            set { studentAction = value; }
        }
        public HandsetActions HandsetAction
        {
            get { return handsetAction; }
            set { handsetAction = value; }
        }
        public InventoryTxnActions TxnAction
        {
            get { return txnAction; }
            set { txnAction = value; }
        }

        public ArsProcessSchedule Schedule
        {
            get { return schedule; }
            set { schedule = value; }
        }

        public void SetView(IViewCheckOut view, IDeviceAPIHelper ars)
        {
            this.view = view;
            view.PropertyChanged += OnViewPropertyChanged;
            view.CheckOutClicked += OnCheckOutClicked;
            view.BarcodeEntered += OnBarcodeEntered;
            view.StudentNoEntered += OnStudentNoEntered;
            view.StudentNameEntered += OnStudentNameEntered;

            arsHelper = ars;
            arsHelper.DataReceived += OnDataReceived;
            arsHelper.DataRegistered += OnDataRegistered;

            schedule.Update(TimeSpan.FromMilliseconds(10000));
            schedule.TerminalProcess += OnTimeOut;
        }

        void OnTimeOut(object sender, EventArgs e)
        {
            arsHelper.StopProcess();

            if (e != EventArgs.Empty)
                throw new Exception(e.ToString());
        }

        void OnDataReceived(object sender, ARSEventArgs e)
        {
            HandsetData keypadData = (HandsetData)e.ReceivedData;
            switch (keypadData.CommandCode)
            {
                case ARSCommandCode.STUDENT_JOIN:
                    arsHelper.StopProcess();
                    schedule.ForceTerminalProcess();                    
                    view.Handset.MAC = keypadData.MacStr;

                    // TODO: Check Handset Status
                    InventoryTxn txn = txnAction.CheckHandsetStatus(view.Handset.MAC);
                    if (txn != null)
                    {
                        if (txn.Status == Util.Constants.Status_CheckOut.Id)
                        {
                            throw new Exception(string.Format("{0} was Checked Out.", txn.HandsetID));
                        }
                    }

                    // Enable user to check out handset.

                    break;

                default:
                    break;
            }
        }

        void OnDataRegistered(object sender, ARSRegisterEventArgs e)
        {
            arsHelper.StopProcess();
            schedule.ForceTerminalProcess();

            bool success = (bool)e.Registered;
            string Id = (string)e.Id;

            if ((bool)e.Registered)
            {
                SaveTxn();
            }
        }

        void OnBarcodeEntered(object sender, EventArgs e)
        {
            StudentInfo student = studentAction.FindStudentByBarcode(view.Student.Barcode);
            checkStudentStatus(student);
        }

        void OnStudentNoEntered(object sender, EventArgs e)
        {
            if (view.Student.Barcode == view.Student.StudentNo)
            {
                throw new Exception("Student No and Barcode can not be the same.");
            }
            StudentInfo student = studentAction.FindStudentByNo(view.Student.StudentNo);
            checkStudentStatus(student);
        }

        void OnStudentNameEntered(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(view.Student.Barcode)
                || string.IsNullOrEmpty(view.Student.StudentNo))
            {
                throw new Exception("Please Enter Barcode / StudentId first.");
            }
            arsHelper.StartProcess();
            schedule.Start();
        }

        void checkStudentStatus(StudentInfo student)
        {
            if (student != null)
            {
                view.Student = student;
                InventoryTxn txn = txnAction.CheckStudentStatus(student.StudentNo);
                if (txn != null)
                {
                    if (txn.Status == Util.Constants.Status_CheckOut.Id)
                    {
                        throw new Exception(string.Format("{0} ({1}) was Checked Out.", student.StudentName, txn.StudentID));
                    }
                }
                arsHelper.StartProcess();
                schedule.Start();
            }
            else
            {
                throw new Exception("Student not found!");
            }
        }

        private void OnViewPropertyChanged(object sender, PropertyChangedEventArgs e)
        {

        }

        private void OnCheckOutClicked(object sender, EventArgs e)
        {
            arsHelper.RegristerHandset(view.Student.StudentNo, view.IsDisplayRID);
            schedule.Start();
        }

        void SaveTxn()
        {
            // TODO: Save Student and Check Out transaction
            try
            {
                if (view.Student.Id < 1)
                {
                    object objID = studentAction.CreateNewStudent();
                    if (objID != null && Convert.ToInt32(objID) > 1)
                    {
                        view.Student.Id = Convert.ToInt32(objID);
                    }
                }

                if (handsetAction.CheckHandset(view.Handset.MAC) == null)
                {
                    InventoryTable inventoryTable = new InventoryTable();
                    inventoryTable.HandsetID = view.Handset.MAC;
                    inventoryTable.TxnTime = DateTime.Now;
                    inventoryTable.IsActive = true;

                    object inventTblID = handsetAction.CreateNewHandset(inventoryTable);
                }

                InventoryTxn inventoryTxn = new InventoryTxn();
                inventoryTxn.HandsetID = view.Handset.MAC;
                inventoryTxn.StudentID = view.Student.StudentNo;
                inventoryTxn.TxnTime = DateTime.Now;
                inventoryTxn.Remark = view.EventRemark;
                inventoryTxn.Status = Util.Constants.Status_CheckOut.Id;
                inventoryTxn.UserEvent = Util.Constants.Status_CheckOut.StatusDesc;
                inventoryTxn.NeedPay = false;
                inventoryTxn.PaymentNo = string.Empty;
                inventoryTxn.IsOverride = false;
                inventoryTxn.OverrideStatus = -1;

                object txnID = txnAction.CreateNewTxn(inventoryTxn);
                if (txnID != null && Convert.ToInt32(txnID) > 1)
                {

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

    }
}
